/**
 * Created by zhulifeng on 2023/7/28.
 * */
#ifndef MIDDLEWARE_AUTODETECTETHERNETWRITER_H
#define MIDDLEWARE_AUTODETECTETHERNETWRITER_H

#include <DeviceWriter.h>
#include <InterfaceInfo.h>
#include <map>
#include <pthread.h>
#include <vector>
#include "Wrapper.h"
#include "Function.h"

class TCPClient;

class UDPClient;

/**
 * 与一个接口匹配的数据写出
 */
struct ServiceConnectInfo {
    InterfaceInfo ifInfo;
    TCPClient *tcpClient = 0;
    UDPClient *udpClient = 0;
    bool initSuccess;//客户端自己记录到的健康状态，目前只对tcp有效
    bool toDelete; //标记是否应该被删除，接口状态发生变化时刷新
};

/**
 * 按照主题获取连接信息，给所有订阅发送数据
 */
class AutoDetectEthernetWriter : public DeviceWriter {
public:
    std::string ifName;
    std::string dataStruct;

    AutoDetectEthernetWriter(std::string ifName, std::string dataStruct, bool isBlocking);

    ~AutoDetectEthernetWriter();

    void stop() override;

    void setupConnection() override;

    int64_t onWrite(char *buffer, int64_t len) override;

    /**
     * 返回socket描述符，一般在 setPostSetupAction() 中使用
     * 
     * @return SOCKET, 无效时返回INVALID_SOCKET
     */
    SOCKET getSocket(ServiceConnectInfo *info);

    /**
     * 设置 setupConnection() 完成后动作
     * 
     * 传入的函数应同时在 AppDelegate::onConfigure() 中使用 REGISTER_FUNCTIONS() 进行注册
     */
    FLOW_API void setPostSetupAction(void (*func)(AutoDetectEthernetWriter *, ServiceConnectInfo *info));

    void wait();

    void waitTimeout(int milliseconds);

    void notify_one();

    void notify_all();

private:
    pthread_mutex_t _lock_mutex; //加锁用
    pthread_mutex_t _mutex; //阻塞用
    pthread_cond_t _cond;
    std::map<std::string, ServiceConnectInfo *> connections;
    Function postSetupAction;
    unsigned int mcTTL = 0;
    bool isBlocking = true;

    static void outputIfReceivedCb(void *param, std::vector<InterfaceInfo> &records);

    void initConnections(std::vector<InterfaceInfo> &records);

    void setupOneConnection(ServiceConnectInfo *info);
};


#endif //MIDDLEWARE_AUTODETECTETHERNETWRITER_H
